package apiAccess;

import java.io.*;
import java.util.LinkedList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;


public class APIAccess {

    	static class LanguageListParser extends DefaultHandler{
                private boolean error=false;
		private boolean bool;
		private String tmpData;
		private List<Language> tmpList;
		private int id;
		private String name;
		private String code;


		@Override
		public void startElement(String uri, String name, String qName, Attributes atts) {
			if(qName.equalsIgnoreCase("response")) {
				if(!atts.getValue("status").equalsIgnoreCase("ok")){
					error=true;
				}
			}else if(qName.equalsIgnoreCase("languages")) {
				tmpList=new LinkedList<Language>();
			}else if(qName.equalsIgnoreCase("language")) {
				id=Integer.parseInt(atts.getValue("id"));
			}else if(qName.equalsIgnoreCase("code")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("name")) {
				bool=true;
			}
		}

		@Override
		public void characters(char[] ch, int start, int length) throws SAXException{
				if(bool){
					tmpData=new String(ch,start,length);
				}
		}

		@Override
		public void endElement(String uri, String localName, String qName){
			if(qName.equalsIgnoreCase("language")) {
				tmpList.add(new Language(id,code,name));
			}else if(qName.equalsIgnoreCase("code")) {
				code=tmpData;
			}else if(qName.equalsIgnoreCase("name")) {
				name=tmpData;
			}
			bool=false;
		}

	}
        
        
        
	public static List<Language> getLanguageList() throws SAXException, IOException, APIEXception{
		XMLReader xr= null;
		xr = XMLReaderFactory.createXMLReader();
		LanguageListParser parse= new LanguageListParser();
		xr.setContentHandler(parse);
		xr.parse("http://eiffel.itba.edu.ar/hci/service/Common.groovy?method=GetLanguageList");
                if(parse.error)
                    throw new APIEXception();
                return parse.tmpList;
	}



    public static List<Category> getCategoryList(int languageId) throws SAXException, IOException, APIEXception {
                XMLReader xr= null;
		xr = XMLReaderFactory.createXMLReader();
		CategoryListParser parse= new CategoryListParser();
		xr.setContentHandler(parse);
		xr.parse("http://eiffel.itba.edu.ar/hci/service/Catalog.groovy?method=GetCategoryList&language_id="+ languageId);
                if(parse.error)
                    throw new APIEXception();
                return parse.tmpList;
    }


    private static class CategoryListParser extends DefaultHandler{
                private boolean error;
		private boolean bool;
		private String tmpData;
		private List<Category> tmpList;
		private int id;
		private String name;
		private String code;


                @Override
		public void startElement(String uri, String name, String qName, Attributes atts) {
			if(qName.equalsIgnoreCase("response")) {
				if(!atts.getValue("status").equalsIgnoreCase("ok")){
					error=true;
				}
			}else if(qName.equalsIgnoreCase("categories")) {
				tmpList=new LinkedList<Category>();
			}else if(qName.equalsIgnoreCase("category")) {
				id=Integer.parseInt(atts.getValue("id"));
			}else if(qName.equalsIgnoreCase("code")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("name")) {
				bool=true;
			}
		}

		@Override
		public void characters(char[] ch, int start, int length) throws SAXException{
				if(bool){
					tmpData=new String(ch,start,length);
				}
		}

		@Override
		public void endElement(String uri, String localName, String qName){
			if(qName.equalsIgnoreCase("category")) {
				tmpList.add(new Category(id,code,name));
			}else if(qName.equalsIgnoreCase("code")) {
				code=tmpData;
			}else if(qName.equalsIgnoreCase("name")) {
				name=tmpData;
			}
			bool=false;
		}
    }

    public static List<SubCategory> getSubCategoryList(int category_id, int languageId) throws SAXException, IOException, APIEXception {
                XMLReader xr= null;
		xr = XMLReaderFactory.createXMLReader();
		SubCategoryListParser parse= new SubCategoryListParser();
		xr.setContentHandler(parse);
		xr.parse("http://eiffel.itba.edu.ar/hci/service/Catalog.groovy?method=GetSubcategoryList&language_id="+languageId+"&category_id="+category_id+"");
		if(parse.error)
                    throw new APIEXception();
                return parse.tmpList;
    }


    private static class SubCategoryListParser extends DefaultHandler{
                private boolean error;
		private boolean bool;
		private String tmpData;
		private List<SubCategory> tmpList;
		private int id;
		private int category_id;
		private String name;
		private String code;


                @Override
		public void startElement(String uri, String name, String qName, Attributes atts) {
			if(qName.equalsIgnoreCase("response")) {
				if(!atts.getValue("status").equalsIgnoreCase("ok")){
					error=true;
				}
			}else if(qName.equalsIgnoreCase("subcategories")) {
				tmpList=new LinkedList<SubCategory>();
			}else if(qName.equalsIgnoreCase("subcategory")) {
				id=Integer.parseInt(atts.getValue("id"));
			}else if(qName.equalsIgnoreCase("category_id")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("code")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("name")) {
				bool=true;
			}
		}

		@Override
		public void characters(char[] ch, int start, int length) throws SAXException{
				if(bool){
					tmpData=new String(ch,start,length);
				}
		}

		@Override
		public void endElement(String uri, String localName, String qName){
			if(qName.equalsIgnoreCase("subcategory")) {
				tmpList.add(new SubCategory(id,category_id,code,name));
			}else if(qName.equalsIgnoreCase("category_id")) {
				category_id=Integer.parseInt(tmpData);
			}else if(qName.equalsIgnoreCase("code")) {
				code=tmpData;
			}else if(qName.equalsIgnoreCase("name")) {
				name=tmpData;
			}
			bool=false;
		}
    }

    public static List<Items> getCategItemsList(int category_id, int languageId) throws SAXException, IOException, APIEXception {
                XMLReader xr= null;
		xr = XMLReaderFactory.createXMLReader();
		ItemsListParser parse= new ItemsListParser();
		xr.setContentHandler(parse);
		xr.parse("http://eiffel.itba.edu.ar/hci/service/Catalog.groovy?method=GetProductListByCategory&language_id="+languageId+"&category_id="+category_id+"");
                if(parse.error)
                    throw new APIEXception();
                return parse.tmpList;
    }


    public static List<Items> getSubCategItemsList(int category_id, int subcategory_id, int languageId) throws SAXException, IOException, APIEXception {
                XMLReader xr= null;
		xr = XMLReaderFactory.createXMLReader();
		ItemsListParser parse= new ItemsListParser();
		xr.setContentHandler(parse);
		xr.parse("http://eiffel.itba.edu.ar/hci/service/Catalog.groovy?method=GetProductListBySubcategory&language_id="+languageId+"&category_id="+category_id+"&subcategory_id="+subcategory_id+"");
		if(parse.error)
                    throw new APIEXception();
                return parse.tmpList;
    }
     public static List<Items> getProductListByName(String name) throws APIEXception, IOException, SAXException {
                XMLReader xr= null;
		xr = XMLReaderFactory.createXMLReader();
		ItemsListParser parse= new ItemsListParser();
		xr.setContentHandler(parse);
		xr.parse("http://eiffel.itba.edu.ar/hci/service/Catalog.groovy?method=GetProductListByName&criteria="+name+"");
		if(parse.error)
                    throw new APIEXception();
                return parse.tmpList;
    }
    private static class ItemsListParser extends DefaultHandler{
                private boolean error;
		private boolean bool;
		private String tmpData;
		private List<Items> tmpList;
                private int id;
                private int category_id;
                private int subcategory_id;
                private String name;
                private int sales_rank;
                private double price;
                private String image_url;


                @Override
		public void startElement(String uri, String name, String qName, Attributes atts) {
			if(qName.equalsIgnoreCase("response")) {
				if(!atts.getValue("status").equalsIgnoreCase("ok")){
					error=true;
				}
			}else if(qName.equalsIgnoreCase("products")) {
				tmpList=new LinkedList<Items>();
			}else if(qName.equalsIgnoreCase("product")) {
				id=Integer.parseInt(atts.getValue("id"));
			}else if(qName.equalsIgnoreCase("category_id")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("subcategory_id")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("name")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("sales_rank")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("price")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("image_url")) {
				bool=true;
			}
		}

		@Override
		public void characters(char[] ch, int start, int length) throws SAXException{
				if(bool){
					tmpData=new String(ch,start,length);
				}
		}

		@Override
		public void endElement(String uri, String localName, String qName){
			if(qName.equalsIgnoreCase("product")) {
				tmpList.add(new Items(id, category_id, subcategory_id, name, image_url));
			}else if(qName.equalsIgnoreCase("category_id")) {
				category_id=Integer.parseInt(tmpData);
			}else if(qName.equalsIgnoreCase("subcategory_id")) {
				subcategory_id=Integer.parseInt(tmpData);
			}else if(qName.equalsIgnoreCase("name")) {
				name=tmpData;
			}else if(qName.equalsIgnoreCase("image_url")) {
				image_url=tmpData;
			}
			bool=false;
		}
    }
    public static Product getProduct(int id) throws SAXException, IOException, APIEXception {
                XMLReader xr= null;
                xr = XMLReaderFactory.createXMLReader();
		ProductParser parse= new ProductParser();
		xr.setContentHandler(parse);
		xr.parse("http://eiffel.itba.edu.ar/hci/service/Catalog.groovy?method=GetProduct&product_id="+id+"");
		if(parse.error)
                    throw new APIEXception();
                return parse.tmpList;
    }

    private static class ProductParser extends DefaultHandler{
                private boolean error;
                private boolean bool;
		private String tmpData;
		private Product tmpList;
		private int id;
                private int category_id;
                private int subcategory_id;
                private String name;
                private int sales_rank;
                private String price;
                private String image_url;
                private String actors;
                private String format;
                private String language;
                private String subtitles;
                private String region;
                private String aspect_ratio;
                private int number_discs;
                private String release_date;
                private String run_time;
                private String publisher;
                private String published_date;
                private String authors;


                @Override
		public void startElement(String uri, String name, String qName, Attributes atts) {
			if(qName.equalsIgnoreCase("response")) {
				if(!atts.getValue("status").equalsIgnoreCase("ok")){
					error=true;
				}
			}else if(qName.equalsIgnoreCase("product")) {
				id=Integer.parseInt(atts.getValue("id"));
			}else if(qName.equalsIgnoreCase("category_id")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("subcategory_id")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("name")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("sales_rank")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("price")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("image_url")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("publisher")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("published_date")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("authors")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("actors")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("format")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("language")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("subtitles")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("region")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("aspect_ratio")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("number_discs")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("release_date")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("run_time")) {
				bool=true;
			}
		}

		@Override
		public void characters(char[] ch, int start, int length) throws SAXException{
				if(bool){
					tmpData=new String(ch,start,length);
				}
		}

		@Override
		public void endElement(String uri, String localName, String qName){
			if(qName.equalsIgnoreCase("product")) {
                            if(category_id==1){
                                tmpList=new Product(id,category_id,subcategory_id,name,image_url,sales_rank,
                                        price,actors,format,language,subtitles,region,
                                        aspect_ratio,number_discs,release_date,run_time);
                                }else if(category_id==2){
                                tmpList=new Product(id,category_id,subcategory_id,name,image_url,sales_rank,
                                        price,language,authors,publisher, published_date);
                                }

			}else if(qName.equalsIgnoreCase("category_id")) {
				category_id=Integer.parseInt(tmpData);
			}else if(qName.equalsIgnoreCase("subcategory_id")) {
				subcategory_id=Integer.parseInt(tmpData);
			}else if(qName.equalsIgnoreCase("name")) {
				name=tmpData;
			}else if(qName.equalsIgnoreCase("image_url")) {
				image_url=tmpData;
			}else if(qName.equalsIgnoreCase("sales_rank")) {
				sales_rank=Integer.parseInt(tmpData);
			}else if(qName.equalsIgnoreCase("price")) {
				price=tmpData;
			}else if(qName.equalsIgnoreCase("publisher")) {
				publisher=tmpData;
			}else if(qName.equalsIgnoreCase("published_date")) {
				published_date=tmpData;
			}else if(qName.equalsIgnoreCase("authors")) {
				authors=tmpData;
			}else if(qName.equalsIgnoreCase("actors")) {
				actors=tmpData;
			}else if(qName.equalsIgnoreCase("format")) {
				format=tmpData;
			}else if(qName.equalsIgnoreCase("language")) {
				language=tmpData;
			}else if(qName.equalsIgnoreCase("subtitles")) {
				subtitles=tmpData;
			}else if(qName.equalsIgnoreCase("region")) {
				region=tmpData;
			}else if(qName.equalsIgnoreCase("aspect_ratio")) {
				aspect_ratio=tmpData;
			}else if(qName.equalsIgnoreCase("number_discs")) {
				number_discs=Integer.parseInt(tmpData);
			}else if(qName.equalsIgnoreCase("release_date")) {
				release_date=tmpData;
			}else if(qName.equalsIgnoreCase("run_time")) {
				run_time=tmpData;
			}
			bool=false;
		}
    }

    public static String getProductName(int id) throws SAXException, IOException, APIEXception{
                XMLReader xr= null;
                xr = XMLReaderFactory.createXMLReader();
		NameParser parse= new NameParser();
		xr.setContentHandler(parse);
		xr.parse("http://eiffel.itba.edu.ar/hci/service/Catalog.groovy?method=GetProduct&product_id="+id+"");
		if(parse.error)
                    throw new APIEXception();
                return parse.name;
    }

        private static class NameParser extends DefaultHandler{
           private boolean error;
           private boolean bool=false;
           private String tmpData;
           String name;

           @Override
            public void startElement(String uri, String name, String qName, Attributes atts) {
		if(qName.equalsIgnoreCase("response")) {
                    if(!atts.getValue("status").equalsIgnoreCase("ok")){
					error=true;
				}
                }else if(qName.equalsIgnoreCase("name")) {
				bool=true;
		}
            }

            	@Override
		public void characters(char[] ch, int start, int length) throws SAXException{
				if(bool){
					tmpData=new String(ch,start,length);
				}
		}

                @Override
		public void endElement(String uri, String localName, String qName){
                    if(qName.equalsIgnoreCase("name")) {
				name=tmpData;
                    }
                }

    }






            static RankingListParser rankingParser;

            public static void rankingCalculate(int n) throws SAXException, IOException, APIEXception{
                XMLReader xr= null;
                xr = XMLReaderFactory.createXMLReader();
		
		rankingParser= new RankingListParser(n);
		xr.setContentHandler(rankingParser);
		xr.parse("http://eiffel.itba.edu.ar/hci/service/Catalog.groovy?method=GetProductListByCategory&language_id=1&category_id=1");
                xr.parse("http://eiffel.itba.edu.ar/hci/service/Catalog.groovy?method=GetProductListByCategory&language_id=1&category_id=2");
		if(rankingParser.error)
                    throw new APIEXception();
            }

            public static List<String> rankingGetNameList(){
                return rankingParser.nameList;
            }

             public static List<Integer> rankingGetIdeList(){
                return rankingParser.idList;
            }

             public static List<Integer> rankingGetRankingList(){
                return rankingParser.rankingList;
            }


           private static class RankingListParser extends DefaultHandler{
               private boolean error;
		private boolean bool;
		private String tmpData;
		private List<String> nameList=new LinkedList<String>();
                private List<Integer> idList=new LinkedList<Integer>();
                private List<Integer> rankingList=new LinkedList<Integer>();
                private int id;
                private String name;
                private int sales_rank;
                private int n;

                public RankingListParser(int n){
                    this.n=n;
                }

                @Override
		public void startElement(String uri, String name, String qName, Attributes atts) {
			if(qName.equalsIgnoreCase("response")) {
				if(!atts.getValue("status").equalsIgnoreCase("ok")){
					error=true;
				}
			}else if(qName.equalsIgnoreCase("product")) {
				id=Integer.parseInt(atts.getValue("id"));
			}else if(qName.equalsIgnoreCase("name")) {
				bool=true;
			}else if(qName.equalsIgnoreCase("sales_rank")) {
				bool=true;
			}
		}

		@Override
		public void characters(char[] ch, int start, int length) throws SAXException{
				if(bool){
					tmpData=new String(ch,start,length);
				}
		}

		@Override
		public void endElement(String uri, String localName, String qName){
			if(qName.equalsIgnoreCase("product")) {
				if(sales_rank<n){
                                    nameList.add(name);
                                    idList.add(id);
                                    rankingList.add(sales_rank);
                                }
			}else if(qName.equalsIgnoreCase("sales_rank")) {
				sales_rank=Integer.parseInt(tmpData);
			}else if(qName.equalsIgnoreCase("name")) {
				name=tmpData;
			}
			bool=false;
		}
    }




}